#include "core.h"
#include "xTimer.h"
#include "xTime.h"

CTimerBase::CTimerBase(U32 nFrequence)
: m_nFrequence(nFrequence)
, m_bEnable(FALSE)
{
	m_nTimerID = CTimerMgr::getInstance()->AddTimer(this);
}

CTimerBase::~CTimerBase()
{
	CTimerMgr::getInstance()->RemoveTimer(this);
}

void CTimerBase::Tick(U32 nCurTime)
{
	U32 nEsc = SafeSub(nCurTime, m_nLastTickTime);
	if ( nEsc > m_nFrequence)
	{
		BOOL bContinue = onTimer(nCurTime);
		m_nLastTickTime += m_nFrequence;
		if (!bContinue)
		{
			CTimerMgr::getInstance()->RemoveTimer(this);
		}
	}
}

void CTimerBase::Start()
{
	m_bEnable = TRUE;
	m_nLastTickTime = (U32)xTime::getTime();
}

void CTimerBase::Stop()
{
	m_bEnable = FALSE;
}

//-------------------------------------------------------------------------------------------------------
IMP_SINGLETON_CLASS(CTimerMgr)

CTimerMgr::CTimerMgr()
: m_nTimerID(1)
{

}

U32 CTimerMgr::AddTimer(CTimerBase* pTB)
{
	if(pTB)
	{
		m_nTimerID++;
		pTB->m_nTimerID = m_nTimerID;
		m_mapTimers.insert(TimerMap::value_type(m_nTimerID, pTB));
	}
	return m_nTimerID;
}

void CTimerMgr::RemoveTimer(CTimerBase* pTB)
{
	if (pTB)
	{
		pTB->m_bEnable = FALSE;
		TimerMap::iterator it = m_mapTimers.find(pTB->m_nTimerID);
		if (it != m_mapTimers.end())
		{
			m_mapTimers.erase(it);
		}
	}
}

void CTimerMgr::Tick(U32 nCurtime)
{
	for (TimerMap::iterator it = m_mapTimers.begin(); it != m_mapTimers.end(); ++it)
	{
		CTimerBase *pTB = it->second;
		if (pTB->m_bEnable)
		{
			pTB->Tick(nCurtime);
		}
	}
}